package com.dotndot.controller.network;

import java.io.*;
import java.util.*;

import org.apache.http.*;
import org.apache.http.client.*;
import org.apache.http.client.entity.*;
import org.apache.http.client.methods.*;
import org.apache.http.conn.*;
import org.apache.http.entity.mime.*;
import org.apache.http.impl.client.*;
import org.apache.http.message.*;
import org.apache.http.params.*;
import org.apache.http.protocol.*;

import android.os.*;

import com.dotndot.*;
import com.dotndot.controller.Server.SendServerParam;
import com.dotndot.controller.network.data.*;
import com.dotndot.controller.network.define.INetwork;
import com.dotndot.controller.network.define.INetworkError.*;
import com.dotndot.controller.network.define.INetworkAPI.*;
import com.dotndot.controller.utils.*;
import com.dotndot.controller.utils.Debug;

public class NetworkThread extends Thread implements INetwork
{
    private Handler mManagerHandler;
    private Handler mActivityHandler;
    private String mURI;
    private REQUEST mAPI;
    private REQUEST_TYPE mType;
    private Object mData;
    private final int RET_NETWORK_THREAD = 0;

    public NetworkThread( ReqNetworkData data )
    {
        mManagerHandler = data.getManagerHandler();
        mActivityHandler = data.getActivityHandler();
        mAPI = data.getAPI();
        mType = data.getType();
        mURI = data.getURI();
        mData = data.getData();
        startThred();
    }

    private void startThred()
    {
        this.setDaemon(true);
        this.start();
    }

    public void run()
    {
        HttpPost mHttpPost = new HttpPost(mURI);

        mHttpPost.setHeader("Connection", "Keep-Alive");
        mHttpPost.setHeader("Accept-Charset", "UTF-8");
        mHttpPost.setHeader("ENCTYPE", "multipart/form-data");

        DefaultHttpClient mHttpClient = new DefaultHttpClient();
        HttpConnectionParams.setSoTimeout(mHttpClient.getParams(), SERVER_SOCKET_TIMEOUT);
        HttpConnectionParams.setConnectionTimeout(mHttpClient.getParams(), SERVER_READ_TIMEOUT);

        try
        {
            if( mType == REQUEST_TYPE.NORMAL_POST_TYPE )
            {
                if( mData instanceof ArrayList<?> )
                {
                    List<BasicNameValuePair> normalData = (List<BasicNameValuePair>) mData;
                    UrlEncodedFormEntity paramEntity = new UrlEncodedFormEntity(normalData, HTTP.UTF_8);
                    mHttpPost.setEntity(paramEntity);
                    normalPostPrint(normalData);
                }
            }
            else if( mType == REQUEST_TYPE.MULTIPART_POST_TYPE )
            {
                if( mData instanceof MultipartEntity )
                {
                    MultipartEntity multipartData = (MultipartEntity) mData;
                    mHttpPost.setEntity(multipartData);
                    multipartPostPrint();
                }
            }

            mHttpClient.execute(mHttpPost, mResHandler);

        }
        catch( ConnectTimeoutException e )
        {
            e.printStackTrace();
            respSendMessage(ERROR.RESPONSE_TIME_OUT_ERROR, null);
        }
        catch( IOException e )
        {
            e.printStackTrace();
            respSendMessage(ERROR.RESPONSE_ERROR, null);
        }
        finally
        {
            mHttpClient.getConnectionManager().shutdown();
        }
    }

    ResponseHandler<String> mResHandler = new ResponseHandler<String>()
    {
        public String handleResponse( HttpResponse response )
        {

            InputStream inputStream = null;
            StringBuilder json = new StringBuilder();

            try
            {
                inputStream = response.getEntity().getContent();
                BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));

                for( ;; )
                {
                    String line = br.readLine();
                    if( line == null )
                        break;
                    json.append(line + '\n');
                }

                br.close();
                inputStream.close();

                resultDataPrint(json.toString());
            }
            catch( Exception e )
            {
                e.printStackTrace();
            }

            respSendMessage(ERROR.RESPONSE_SUCCESS, json.toString());
            return null;
        }
    };

    private void normalPostPrint( List<BasicNameValuePair> normalData )
    {
        if( MomApplication._DEBUG_ )
        {
            Debug.printDebug(" \n \n \n______________________________________( REQUEST DATA )______________________________________\n \n");
            Debug.printDebug(" ============================= API = " + mAPI.name());
            Debug.printDebug(" ============================= URI = " + mURI.toString());
            Debug.printDebug(" \n\n");
            for( BasicNameValuePair data : normalData )
            {
                Debug.printDebug(" ============================= [ " + data.getName() + " = " + data.getValue() + " ]");
            }
            Debug.printDebug(" \n______________________________________( REQUEST DATA )______________________________________\n \n");
        }
    }

    private void multipartPostPrint()
    {
        if( MomApplication._DEBUG_ )
        {
            Debug.printDebug(" \n \n \n______________________________________( REQUEST DATA )______________________________________\n \n");
            Debug.printDebug(" ============================= API = " + mAPI.name());
            Debug.printDebug(" ============================= URI = " + mURI.toString());
            Debug.printDebug(" \n\n");
            // for( BasicNameValuePair data : normalData )
            // {
            // Debug.printDebug(" ============================= [ " +
            // data.getName() + " = " + data.getValue() + " ]");
            // }
            Debug.printDebug(" \n______________________________________( REQUEST DATA )______________________________________\n \n");
        }
    }

    private void resultDataPrint( String json )
    {
        if( MomApplication._DEBUG_ )
        {
            Debug.printDebug(" \n \n \n______________________________________( RESULT JSON DATA )______________________________________\n \n");
            Debug.printDebug(" " + json);
            Debug.printDebug(" \n______________________________________( RESULT JSON DATA )______________________________________\n \n");
        }
    }

    // private void xmlDataPrint( InputStream input, ByteArrayOutputStream
    // output ) throws IOException
    // {
    // int length = 0;
    // byte[] buffer = new byte[1024];
    //
    // while( (length = input.read(buffer)) > 0 )
    // {
    // output.write(buffer, 0, length);
    // }
    // String sResult = new String(output.toByteArray());
    // Debug.printDebug(" \n \n \n______________________________________( XML DATA )______________________________________\n \n"
    // + sResult
    // +
    // "\n_______________________________________________________________________________________\n \n \n");
    // }

    private void respSendMessage( ERROR err, Object data )
    {
        RespNetworkData mRespData = new RespNetworkData();
        mRespData.setAPI(mAPI);
        mRespData.setERR(err);
        mRespData.setDATA(data);
        mRespData.setHandler(mActivityHandler);
        Message message = mManagerHandler.obtainMessage(RET_NETWORK_THREAD, mRespData);
        mManagerHandler.sendMessage(message);
    }
}
